package com.szcinda.service.dto.businessCode;

import com.szcinda.repository.BusinessCode;
import com.szcinda.repository.BusinessCodeRepository;
import com.szcinda.repository.User;
import com.szcinda.repository.UserRepository;
import com.szcinda.service.SnowFlakeFactory;
import com.szcinda.service.dto.log.LogCreateDto;
import com.szcinda.service.dto.log.LogService;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;


@Service
@Transactional
public class BusinessServiceImpl implements BusinessService {

    private final BusinessCodeRepository businessCodeRepository;
    private final SnowFlakeFactory snowFlakeFactory;
    private final UserRepository userRepository;
    private final LogService logService;

    public BusinessServiceImpl(BusinessCodeRepository businessCodeRepository, UserRepository userRepository, LogService logService) {
        this.businessCodeRepository = businessCodeRepository;
        this.userRepository = userRepository;
        this.logService = logService;
        this.snowFlakeFactory = SnowFlakeFactory.getInstance();
    }

    @Override
    public void create(BusinessCodeCreateDto codeCreateDto) {
        BusinessCode record = businessCodeRepository.findByName(codeCreateDto.getName());
        Assert.isTrue(record == null, "已经存在[" + codeCreateDto.getName() + "]的业务编号");
        Assert.isTrue(codeCreateDto.getPrefix().length() <= 3, "前缀长度不能大于3位");
        BusinessCode code = new BusinessCode();
        code.setName(codeCreateDto.getName());
        code.setPrefix(codeCreateDto.getPrefix().toUpperCase());
        code.setId(snowFlakeFactory.nextId("BC"));
        businessCodeRepository.save(code);
        User user = userRepository.findById(codeCreateDto.getOpId());
        LogCreateDto createDto = new LogCreateDto(user.getId(), user.getNickName(), "新增业务编号规则", codeCreateDto.getName());
        logService.create(createDto);
    }

    @Override
    public void delete(String id, String userId) {
        BusinessCode record = businessCodeRepository.findById(id);
        businessCodeRepository.delete(record);
        User user = userRepository.findById(userId);
        LogCreateDto createDto = new LogCreateDto(user.getId(), user.getNickName(), "删除业务编号规则", record.getName());
        logService.create(createDto);
    }

    @Override
    public List<BusinessCode> findAll(BusinessCodeQueryDto params) {
        Specification<BusinessCode> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(params.getName())) {
                Predicate site = criteriaBuilder.like(root.get("name").as(String.class), params.getName().trim() + "%");
                predicates.add(site);
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        });
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return businessCodeRepository.findAll(specification, sort);
    }

    @Override
    public List<BusinessCode> getAll() {
        return businessCodeRepository.findAll();
    }
}
